From: Tim Deegan Date: Wed, 7 Feb 2007 17:29:52 +0000 (+0000) Subject: [HVM] Save/restore: don't try to save the MMIO memory-hole at 4GB. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15347^2~11 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=2b30444fe2a045eeaa1e6d7e656ad34989350ebc;p=xen.git [HVM] Save/restore: don't try to save the MMIO memory-hole at 4GB. Also remove two integer arrays that were set to a[i] == i. Signed-off-by: Tim Deegan --- diff --git a/tools/libxc/xc_hvm_save.c b/tools/libxc/xc_hvm_save.c index e6f5ee1dde..fdd2799743 100644 --- a/tools/libxc/xc_hvm_save.c +++ b/tools/libxc/xc_hvm_save.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "xc_private.h" #include "xg_private.h" @@ -275,9 +276,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, /* A copy of the CPU context of the guest. */ vcpu_guest_context_t ctxt; - /* A table containg the type of each PFN (/not/ MFN!). */ - unsigned long *pfn_type = NULL; - unsigned long *pfn_batch = NULL; + /* A table containg the PFNs (/not/ MFN!) to map. */ + xen_pfn_t *pfn_batch = NULL; /* A copy of hvm domain context buffer*/ uint32_t hvm_buf_size; @@ -290,7 +290,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, unsigned char *region_base = NULL; uint32_t nr_pfns, rec_size, nr_vcpus; - unsigned long *page_array = NULL; /* power of 2 order of max_pfn */ int order_nr; @@ -361,18 +360,12 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - max_pfn = live_shinfo->arch.max_pfn; - DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx, nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); - /* nr_pfns: total pages excluding vga acc mem - * max_pfn: nr_pfns + 0x20 vga hole(0xa0~0xc0) - * getdomaininfo.tot_pages: all the allocated pages for this domain - */ if (live) { ERROR("hvm domain doesn't support live migration now.\n"); goto out; - + if (xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, NULL, 0, NULL, 0, NULL) < 0) { @@ -381,6 +374,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } /* excludes vga acc mem */ + /* XXX will need to check whether acceleration is enabled here! */ nr_pfns = info.nr_pages - 0x800; last_iter = 0; @@ -396,8 +390,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, ERROR("HVM Domain appears not to have suspended"); goto out; } - nr_pfns = info.nr_pages; - DPRINTF("after suspend hvm domain nr_pages=0x%x.\n", nr_pfns); + + nr_pfns = info.nr_pages; } DPRINTF("after 1st handle hvm domain nr_pfns=0x%x, nr_pages=0x%lx, max_memkb=0x%lx, live=%d.\n", @@ -406,10 +400,15 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, info.max_memkb, live); - nr_pfns = info.nr_pages; - - /*XXX: caculate the VGA hole*/ - max_pfn = nr_pfns + 0x20; + /* Calculate the highest PFN of "normal" memory: + * HVM memory is sequential except for the VGA and MMIO holes, and + * we have nr_pfns of it (which now excludes the cirrus video RAM) */ + max_pfn = nr_pfns; + /* Skip the VGA hole from 0xa0000 to 0xc0000 */ + max_pfn += 0x20; + /* Skip the MMIO hole: 256MB just below 4GB */ + if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) ) + max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT); skip_this_iter = 0;/*XXX*/ /* pretend we sent all the pages last iteration */ @@ -424,7 +423,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, to_send = malloc(BITMAP_SIZE); to_skip = malloc(BITMAP_SIZE); - page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn); hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0); if ( hvm_buf_size == -1 ) @@ -434,7 +432,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } hvm_buf = malloc(hvm_buf_size); - if (!to_send ||!to_skip ||!page_array ||!hvm_buf) { + if (!to_send ||!to_skip ||!hvm_buf) { ERROR("Couldn't allocate memory"); goto out; } @@ -454,26 +452,16 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, analysis_phase(xc_handle, dom, max_pfn, to_skip, 0); - /* get all the HVM domain pfns */ - for ( i = 0; i < max_pfn; i++) - page_array[i] = i; - /* We want zeroed memory so use calloc rather than malloc. */ - pfn_type = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type)); pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch)); - if ((pfn_type == NULL) || (pfn_batch == NULL)) { - ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays"); + if (pfn_batch == NULL) { + ERROR("failed to alloc memory for pfn_batch array"); errno = ENOMEM; goto out; } - if (lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type))) { - ERROR("Unable to lock"); - goto out; - } - /* Start writing out the saved-domain record. */ if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) { ERROR("write: max_pfn"); @@ -511,16 +499,15 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } - /* load pfn_type[] with the mfn of all the pages we're doing in + /* load pfn_batch[] with the mfn of all the pages we're doing in this batch. */ for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) { int n = permute(N, max_pfn, order_nr); if (debug) { - DPRINTF("%d pfn= %08lx mfn= %08lx %d \n", - iter, (unsigned long)n, page_array[n], - test_bit(n, to_send)); + DPRINTF("%d pfn= %08lx %d \n", + iter, (unsigned long)n, test_bit(n, to_send)); } if (!last_iter && test_bit(n, to_send)&& test_bit(n, to_skip)) @@ -530,10 +517,12 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, (test_bit(n, to_send) && last_iter))) continue; - if (n >= 0xa0 && n < 0xc0) { -/* DPRINTF("get a vga hole pfn= %x.\n", n);*/ + /* Skip PFNs that aren't really there */ + if ((n >= 0xa0 && n < 0xc0) /* VGA hole */ + || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) + && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */ continue; - } + /* ** we get here if: ** 1. page is marked to_send & hasn't already been re-dirtied @@ -541,7 +530,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, */ pfn_batch[batch] = n; - pfn_type[batch] = page_array[n]; batch++; } @@ -573,7 +561,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - sent_this_iter += batch; munmap(region_base, batch*PAGE_SIZE); @@ -723,9 +710,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } free(hvm_buf); - free(page_array); - - free(pfn_type); free(pfn_batch); free(to_send); free(to_skip);